package com.dianzhihan.cashier.controller;

import com.dianzhihan.cashier.model.order.Order;
import com.dianzhihan.cashier.model.order.OrderDetail;
import com.dianzhihan.cashier.model.product.Product;
import com.dianzhihan.cashier.model.product.ProductParam;
import com.dianzhihan.cashier.model.user.PasswordValidator;
import com.dianzhihan.cashier.model.user.User;
import com.dianzhihan.cashier.model.user.UsernameValidator;
import com.dianzhihan.cashier.service.OrderService;
import com.dianzhihan.cashier.service.ProductService;
import com.dianzhihan.cashier.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.HashMap;

/**
 * @author Dianzhi Han
 * @version 1.0
 * @description: Controller 类，专门存放.do结尾的资源
 * @date 2023/2/5 13:09
 */

@Slf4j
@Controller
public class DoController {
    private final UserService userService;
    private final UsernameValidator usernameValidator;
    private final PasswordValidator passwordValidator;
    private final ProductService productService;
    private final OrderService orderService;

    @Autowired
    public DoController(UserService userService, UsernameValidator usernameValidator, PasswordValidator passwordValidator, ProductService productService, OrderService orderService) {
        this.userService = userService;
        this.usernameValidator = usernameValidator;
        this.passwordValidator = passwordValidator;
        this.productService = productService;
        this.orderService = orderService;
    }
    @PostMapping("/register.do")
    //由于参数名称和 form 表单里的 input 的 name 是对应上的，所以省略了 @RequestParam 注解
    public String register(String username, String password, HttpServletRequest request) {
        //module和redirectUrl是为了让统一异常处理能区分功能
        String module = "用户注册";
        String redirectUrl = "/register.html";

        log.debug("用户注册:用户名是:{}，密码是:{}", username, password);

        // 进行参数的合法性校验
        username = usernameValidator.validate(username,module,redirectUrl);
        //用户名已经合法，开始进行密码的合法性校验
        password = passwordValidator.validate(password,module,redirectUrl);
        // password 是一个合法的密码

        // 完成注册的工作,调用service服务,对密码进行加密
        try {
            User user = userService.register(username, password);

            log.debug("用户注册: 注册成功, user = {}", user);
            // 最终注册成功之后，直接登录，利用Session
            HttpSession session = request.getSession();
            session.setAttribute("currentUser",user);

            //注册完成，跳转首页
            return "redirect:/";
        } catch (DuplicateKeyException exc) {  // 因为数据表定义了username是Unique的，要是重复会出现异常
            throw new ErrorRedirectException("username 重复",module,redirectUrl, exc);
        }

    }

    @PostMapping("/login.do")
    public String login(String username,String password,HttpServletRequest request){
        //module和redirectUrl是为了让统一异常处理能区分功能
        String module = "用户登录";
        String redirectUrl = "/login.html";

        log.debug("用户登录：用户名为：{}，密码为：{}",username,password);
        //合法性校验
        username = usernameValidator.validate(username,module,redirectUrl);
        password = passwordValidator.validate(password,module,redirectUrl);

        //登录逻辑，查询数据库
        User user = userService.login(username,password);

        //如果数据库中查不到这输入的记录，就抛出异常
        if (user == null) {
            throw new ErrorRedirectException("username or password 错误",module,redirectUrl);
        }

        //设置session，保持登录状态
        HttpSession session = request.getSession();
        session.setAttribute("currentUser",user);

        log.debug("用户登录: 登录成功, user = {}", user);

        return "redirect:/";
    }

    @PostMapping("/product/create.do")
    //正常传入form中的属性太多了，创建一个对象接收请求
    //SpringMVC自动帮忙构造ProductParam对象，只要类属性和form中name一致
    public String productCreate(ProductParam productParam,HttpServletRequest request){

        String module = "商品上架";
        String redirectUrl = "/product/create.html";
        log.debug("{},请求的参数为{}",module,productParam);


        User currentUser = null;
        HttpSession session = request.getSession(false);
        if (session != null) {
            currentUser = (User) session.getAttribute("currentUser");
        }

        if (currentUser == null) {
            // 说明用户未登录
            log.debug("{}: 用户未登录，无权进行该操作", module);
            return "redirect:/login.html";  // 重定向到登录页，让用户登录
        }


        // todo: 验证合法性
        productParam.validate(module, redirectUrl);

        Product product = productService.create(currentUser,productParam);

        log.debug("{}: 成功，上架商品为: {}", module, product);

        //跳转到商品列表页
        return  "redirect:/product/list.html";
    }

    @GetMapping("/product/withdraw.do")
    public String productWithdraw(String id, HttpServletRequest request){
        String module = "商品下架";
        String redirectUrl = "/product/withdraw.html";
        log.debug("{},商品id为{}",module,id);


        User currentUser = null;
        HttpSession session = request.getSession(false);
        if (session != null) {
            currentUser = (User) session.getAttribute("currentUser");
        }

        if (currentUser == null) {
            // 说明用户未登录
            log.debug("{}: 用户未登录，无权进行该操作", module);
            return "redirect:/login.html";  // 重定向到登录页，让用户登录
        }


        productService.withdraw(Integer.parseInt(id));

        log.debug("{}: 成功，下架商品id为: {}", module, id);

        return "redirect:/product/list.html";

    }

    @PostMapping("/product/update.do")
    //正常传入form中的属性太多了，创建一个对象接收请求
    //SpringMVC自动帮忙构造ProductParam对象，只要类属性和form中name一致
    public String productUpdate(ProductParam productParam,HttpServletRequest request){

        String module = "商品更新";
        String redirectUrl = "/product/update.html";
        log.debug("{},请求的参数为{}",module,productParam);


        User currentUser = null;
        HttpSession session = request.getSession(false);
        if (session != null) {
            currentUser = (User) session.getAttribute("currentUser");
        }

        if (currentUser == null) {
            // 说明用户未登录
            log.debug("{}: 用户未登录，无权进行该操作", module);
            return "redirect:/login.html";  // 重定向到登录页，让用户登录
        }


        // 验证输入的productParam合法性
        productService.validate(productParam,module,redirectUrl);



        Product product = productService.update(currentUser,productParam);

        log.debug("{}: 成功，更新商品为: {}", module, product);

        //跳转到商品列表页
        return  "redirect:/product/list.html";
    }

    //创建订单，根据订单编号uuid返回页面
    @PostMapping("/order/create.do")
    public String orderCreate(@RequestParam("create-param") String createParam,HttpServletRequest request) {
        log.debug("购买商品: createParam = {}", createParam);

        //获取session，获取user
        HttpSession session = request.getSession(false);
        User currentUser = null;
        if (session != null) {
            currentUser = (User) session.getAttribute("currentUser");
        } else {
            // 说明用户未登录,重定向到登录页
            return "redirect:/login.html";
        }

        log.debug("当前用户: user = {}", currentUser);

        HashMap<Integer, Integer> toBoughtProductMap;
        try {
            //因为OrderService类中的create方法需要传入一个带有购买商品id和购买数量的map
            toBoughtProductMap = new HashMap<>();
            //处理传入的字符串并将参数传入map中
            String[] paramArray = createParam.split(",");
            for (String param : paramArray) {
                String[] split = param.split("-");
                String productIdStr = split[0];
                String productNumberStr = split[1];
                //String类型要转成int
                int productId = Integer.parseInt(productIdStr);
                int productNumber = Integer.parseInt(productNumberStr);
                toBoughtProductMap.put(productId, productNumber);
            }

        } catch (Exception exc) {
            throw new ErrorRedirectException("购买商品输入格式应该是 id-数量,id-数量", "购买商品", "/order/create.html");
        }


        log.debug("购买商品：toBoughtProductMap = {}", toBoughtProductMap);




        //创建订单
        Order order = orderService.create(currentUser, toBoughtProductMap);
        log.debug("创建订单: {}", order);

        //给每个订单号做一个订单详情页
        String uuid = order.getUuid();
        return "redirect:/order/detail/" + uuid;

    }


    //每个订单的页面详情页(根据uuid)用模板\
    @GetMapping("/order/detail/{uuid}")
    public String orderDetail(@PathVariable("uuid") String uuid, HttpServletRequest request, Model model){
        log.debug("订单详情: uuid = {}", uuid);

        //获取session，获取user
        HttpSession session = request.getSession(false);
        User currentUser = null;
        if (session!=null){
            currentUser = (User)session.getAttribute("currentUser");
        }else{
            // 说明用户未登录,重定向到登录页
            return "redirect:/login.html";
        }

        log.debug("当前用户: user = {}", currentUser);


        //根据uuid查找order表
        OrderDetail orderDetail = orderService.queryByUuid(uuid);

        log.debug("order = {}", orderDetail);

        model.addAttribute("order", orderDetail);

        return "order-detail";

    }


    //确认订单
    @GetMapping("/order/confirm/{orderId}")
    public String orderConfirm(@PathVariable int orderId, HttpServletRequest request){
        log.debug("确认订单: orderId = {}", orderId);

        User currentUser = null;
        HttpSession session = request.getSession(false);
        if (session != null) {
            currentUser = (User) session.getAttribute("currentUser");
        }

        if (currentUser == null) {
            // 说明用户未登录
            log.debug("确认订单: 用户未登录，无权进行该操作");
            return "redirect:/login.html";  // 重定向到登录页，让用户登录
        }
        log.debug("当前用户: user = {}", currentUser);

        orderService.confirmOrder(orderId);

        return "redirect:/order/list.html";
    }


    //取消订单

    @GetMapping("/order/cancel/{orderId}")
    public String orderCancel(@PathVariable int orderId, HttpServletRequest request) {
        log.debug("取消订单: orderId = {}", orderId);

        User currentUser = null;
        HttpSession session = request.getSession(false);
        if (session != null) {
            currentUser = (User) session.getAttribute("currentUser");
        }

        if (currentUser == null) {
            // 说明用户未登录
            log.debug("取消订单: 用户未登录，无权进行该操作");
            return "redirect:/login.html";  // 重定向到登录页，让用户登录
        }
        log.debug("当前用户: user = {}", currentUser);

        orderService.cancelOrder(orderId);
        return "redirect:/order/list.html";
    }


}
